package demo18

// visitor
import "fmt"
// 客户等待 邀请者的下发邀请
type Customer interface{
	// 接受某某邀请者
	Accept(Visitor)
}
// 邀请者
type Visitor interface{
	// 下发邀请某某客户
	Visit(Customer)
}

// 被邀请前来的客户群体
type CustomerCol struct{
	customers []Customer
}
// 邀请成功的客户，标记一下同时放在文档里等待 某时间一起邀请过来
func (c *CustomerCol)Add(customer Customer){
	c.customers = append(c.customers, customer)
}

func (c *CustomerCol)Accept(visitor Visitor){
	// 所有被邀请过来的客户群里，然后入门分析
	for _, customer := range c.customers{
		visitor.Visit(customer)
	}
}

// --------------------------------------------------
// 下面客户类别可以拓展
// 客户群体分类 <公司老客户>
type EnterpriseCustomer struct{
	name string
}

func NewEnterpriseCustomer(name string) *EnterpriseCustomer{
	return &EnterpriseCustomer{
		name:name,
	}
}

func (c *EnterpriseCustomer)Accept(visitor Visitor){
	// 同样被要请 
	// 下面这个邀请的方法可有可无都能实现，
	// 这个方法可有做一些其他的处理，比如被邀请时候需要带什么资料等一下验证
	visitor.Visit(c)
}

// 新客户， 
type IndividualCustomer struct{
	name string
}

func NewIndividualCustomer(name string) *IndividualCustomer{
	return &IndividualCustomer{
		name:name,
	}
}

func (c *IndividualCustomer)Accept(visitor Visitor){
	visitor.Visit(c)
}
// --------------------------------------------------
// 分析来参见的客户群类
type ServiceCustomer struct{}

func (s *ServiceCustomer)Visit(customer Customer){
	switch c := customer.(type) {
	case *EnterpriseCustomer:
		fmt.Printf("enterprise customer :%s\n",c.name)
	case *IndividualCustomer:
		fmt.Printf("individual customer :%s\n",c.name)
	}
}

// 也可以只统计老客户
type ServiceEnterpriseCustomer struct{}

func (s *ServiceEnterpriseCustomer)Visit(customer Customer){
	switch c := customer.(type) {
	case *EnterpriseCustomer:
		// 验证实现的地方可以在这里做区分，
		// 不同的邀请这里，区分不同的客户群里 在这里通过customer携带的Accept方法来完成
		
		fmt.Printf("enterprise customer :%s\n",c.name)
	}
}
